// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace MigrateTypes {
  export type MigrationDirectory = {
    /**
     * Relative path to a migration directory from `baseDir`.
     * E.g., `./20201117144659_test`.
     */
    path: string
    /**
     * Description of the migration file in the directory.
     */
    migrationFile: {
      /**
       * Relative path to the migration file from `path`.
       */
      path: 'migration.sql'
      /**
       * Content of the migration file.
       * E.g.,
       * ```sql
       * -- CreateTable
       * CREATE TABLE "Blog" (
       *     "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
       *
       *     "viewCount20" INTEGER NOT NULL
       * );
       * ```
       */
      content: Tagged<'ok', { value: string }> | Tagged<'error', { value: string }>
    }
  }

  export type MigrationLockfile = {
    /**
     * Relative path to the lockfile from `baseDir`.
     */
    path: 'migration_lock.toml'
    /**
     * Content of the lockfile, if it exists.
     * E.g.,
     * ```toml
     * # Please do not edit this file manually
     * provider = "sqlite"
     * ```
     */
    content: string | null
  }

  export type MigrationList = {
    /**
     * Absolute path to the base directory of Prisma migrations.
     * E.g., `/usr/src/app/prisma/migrations`.
     */
    baseDir: string

    /**
     * Description of the lockfile, which may or may not exist.
     */
    lockfile: MigrationLockfile

    /**
     * An init script that will be run on the shadow database before the migrations are applied.
     * Useful in combination with external tables. Can be empty.
     * Set via `migrations.initShadowDb` in `prisma.config.ts`.
     */
    shadowDbInitScript: string

    /**
     * Description of the migration directories.
     */
    migrationDirectories: Array<MigrationDirectory>
  }

  export type SchemaContainer = {
    path: string
    content: string
  }

  export type SchemasContainer = {
    files: SchemaContainer[]
  }

  export type SchemasWithConfigDir = {
    files: SchemaContainer[]
    configDir: string
  }

  export type SchemaFilter = {
    externalTables: string[]
    externalEnums: string[]
  }

  export type UrlContainer = {
    url: string
  }

  export type DatasourceParam = Tagged<'ConnectionString', UrlContainer> | Tagged<'Schema', SchemasContainer>
  export type GetDatabaseVersionParams = {
    datasource: MigrateTypes.DatasourceParam
  }

  // Helper type for creating tagged enum variants
  export type Tagged<Tag extends string, T> = Display<{ tag: Tag } & T>

  // Helper to force TS to display the fields of computed types, rather than type name
  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
  export type Display<T> = { [K in keyof T]: T[K] } & unknown
}
